
package com.myshoutui.manager;

import java.util.ArrayList;
import java.util.HashMap;

public class AnalyzedQuery {

    private static HashMap<String, String> presentationMap = null;
    private static HashMap<String, String> endearmentMap = null;
    private static HashMap<String, String> verbsMap = null;
    private static HashMap<String, String> generalizationsMap = null;
    private static HashMap<String, String> prepositionsMap = null;
    private static HashMap<String, String> substitutionsMap = null;

    static {
        if (presentationMap == null)
            presentationMap = new HashMap<String, String>();

        if (endearmentMap == null)
            endearmentMap = new HashMap<String, String>();

        if (verbsMap == null)
            verbsMap = new HashMap<String, String>();

        if (generalizationsMap == null)
            generalizationsMap = new HashMap<String, String>();

        if (substitutionsMap == null)
            substitutionsMap = new HashMap<String, String>();

        if (prepositionsMap == null)
            prepositionsMap = new HashMap<String, String>();

        // Presentation criteria
        presentationMap.put("closest", "nearest");
        presentationMap.put("nearest", "nearest");
        presentationMap.put("close", "nearest");
        presentationMap.put("near", "nearest");
        presentationMap.put("nearby", "nearest");
        presentationMap.put("neighborhood", "nearest");
        presentationMap.put("quick", "nearest");
        presentationMap.put("quickest", "nearest");

        presentationMap.put("best", "best");
        presentationMap.put("popular", "best");
        presentationMap.put("best", "best");
        presentationMap.put("good", "best");
        presentationMap.put("excellent", "best");
        presentationMap.put("cool", "best");
        presentationMap.put("coolest", "best");
        presentationMap.put("favorite", "best");

        presentationMap.put("cheap", "price");
        presentationMap.put("cheapest", "price");

        // Ignore if Previous term is a valid search term
        generalizationsMap.put("restaurants", "");
        generalizationsMap.put("restaurant", "");
        generalizationsMap.put("store", "");
        generalizationsMap.put("stores", "");
        generalizationsMap.put("place", "");
        generalizationsMap.put("places", "");
        generalizationsMap.put("food", "");
        generalizationsMap.put("shop", "");
        generalizationsMap.put("shops", "");
        generalizationsMap.put("cuisine", "");
        generalizationsMap.put("joint", "");
        generalizationsMap.put("joints", "");

        // Verbs
        verbsMap.put("like", "");
        verbsMap.put("find", "");
        verbsMap.put("eat", "");
        verbsMap.put("eating", "");
        verbsMap.put("love", "");
        verbsMap.put("eating", "");
        verbsMap.put("looking", "");
        verbsMap.put("search", "");
        verbsMap.put("searching", "");
        verbsMap.put("desperate", "");
        verbsMap.put("dying", "");
        verbsMap.put("want", "");
        verbsMap.put("get", "");
        verbsMap.put("feel", "");
        verbsMap.put("feeling", "");
        verbsMap.put("get", "");

        // Substitutions
        substitutionsMap.put("hungry", "food");
        substitutionsMap.put("thirsty", "juice");
        substitutionsMap.put("sick", "hospital");
        substitutionsMap.put("lonely", "club");
        substitutionsMap.put("sad", "shopping");
        substitutionsMap.put("spicy", "indian,thai");

        // Other scrap tokens
        prepositionsMap.put("i", "");
        prepositionsMap.put("i'm", "");
        prepositionsMap.put("a", "");
        prepositionsMap.put("an", "");
        prepositionsMap.put("me", "");
        prepositionsMap.put("much", "");
        prepositionsMap.put("lets", "");
        prepositionsMap.put("would", "");
        prepositionsMap.put("so", "");
        prepositionsMap.put("to", "");
        prepositionsMap.put("of", "");
        prepositionsMap.put("for", "");
        prepositionsMap.put("off", "");
        prepositionsMap.put("for", "");
        prepositionsMap.put("the", "");
        prepositionsMap.put("am", "");
        prepositionsMap.put("what", "");
        prepositionsMap.put("are", "");
        prepositionsMap.put("the", "");
        prepositionsMap.put("some", "");
        prepositionsMap.put("around", "");
        prepositionsMap.put("by", "");
        prepositionsMap.put("here", "");

        // Endearments
        endearmentMap.put("babu", "");
        endearmentMap.put("papa", "");
        endearmentMap.put("dude", "");
        endearmentMap.put("dear", "");
    }

    public enum OUTPUT_ORDERING {
        SORT_BY_RATING, SORT_BY_PRICE, SORT_BY_DISTANCE, AS_IS
    };

    public ArrayList<String> getOutputTerms() {
        return outputTerms;
    }

    private void addOutputTerms(String[] terms) {
        for (String s : terms)
            outputTerms.add(s);
    }

    private void addOutputTerm(String term) {
        outputTerms.add(term);
    }

    public void setOutputTerms(ArrayList<String> outputTerms) {
        this.outputTerms = outputTerms;
    }

    public OUTPUT_ORDERING getPresentationOrder() {
        return presentationOrder;
    }

    public void setPresentationOrder(OUTPUT_ORDERING presentationOrder) {
        this.presentationOrder = presentationOrder;
    }

    public ArrayList<String> outputTerms;
    public OUTPUT_ORDERING presentationOrder;

    public AnalyzedQuery() {
        presentationOrder = OUTPUT_ORDERING.AS_IS;
        outputTerms = new ArrayList<String>();
    }

    public static AnalyzedQuery analyze(String searchString) {

        AnalyzedQuery result = new AnalyzedQuery();
        result.setPresentationOrder(OUTPUT_ORDERING.AS_IS);

        String[] searchWords = searchString.toLowerCase().split(" ");
        if (searchWords.length == 1) {
            result.addOutputTerms(searchWords);
            return result;
        }

        String prevTerm = null;
        for (String term : searchWords) {
            String processedTerm = process(term, prevTerm, result);
            prevTerm = (processedTerm != null ? processedTerm : prevTerm);
            if ("".equals(processedTerm))
                continue;
            else if (processedTerm != null && processedTerm.contains(",")) {
                String[] searchWords2 = processedTerm.toLowerCase().split(",");
                result.addOutputTerms(searchWords2);
            } else if (processedTerm != null)
                result.addOutputTerm(processedTerm);
        }

        return result;
    }

    private static String process(String term, String prevTerm, AnalyzedQuery output) {

        /*
         * private static HashMap<String, String> presentationMap = null;
         * private static HashMap<String, String> endearmentMap = null; private
         * static HashMap<String, String> verbsMap = null; private static
         * HashMap<String, String> prepositionsMap = null; private static
         * HashMap<String, String> generalizationsMap = null; private static
         * HashMap<String, String> substitutionsMap = null;
         */
        String sortBy = presentationMap.get(term);
        if ("nearest".equals(sortBy))
            output.setPresentationOrder(OUTPUT_ORDERING.SORT_BY_DISTANCE);
        else if ("best".equals(sortBy))
            output.setPresentationOrder(OUTPUT_ORDERING.SORT_BY_RATING);
        else if ("price".equals(sortBy))
            output.setPresentationOrder(OUTPUT_ORDERING.SORT_BY_PRICE);

        if (sortBy != null)
            return "";

        if (prepositionsMap.get(term) != null || verbsMap.get(term) != null || endearmentMap.get(term) != null)
            return null;

        if (generalizationsMap.get(term) != null)
            return (prevTerm == null ? term : "");

        String substitutions = substitutionsMap.get(term);
        if (substitutions != null)
            return substitutions;

        return term;

    }

    public String toString() {
        StringBuilder sb = new StringBuilder();
        if (presentationOrder == OUTPUT_ORDERING.SORT_BY_DISTANCE)
            sb.append("Nearest").append(" ");
        else if (presentationOrder == OUTPUT_ORDERING.SORT_BY_RATING)
            sb.append("Best").append(" ");
        else if (presentationOrder == OUTPUT_ORDERING.SORT_BY_PRICE)
            sb.append("Cheapest").append(" ");

        for (String s : outputTerms) {
            sb.append(s).append(" ");
        }

        return sb.toString();
    }
}
